package mh;

import java.awt.Rectangle;

import mh.interfaces.Constants;
import mh.interfaces.IImage;

/**
 * Define the baseline for <code>PlayerEntity</code>, <code>OtherEntity</code> and <code>SpriteEntity</code>.<br>
 * This abstract class represent each player or any other thing that is moving in the map.
 * 
 * @author Gianmarco Laggia
 * 
 */
public abstract class Entity implements Constants {

	// ============================================ //
	//                   GRAPHICS                   //
	// ============================================ //
	/**
	 * Actual position of this entity in the map (tile unit)
	 */
	protected double			actualX;
	/**
	 * Actual position of this entity in the map (tile unit)
	 */
	protected double			actualY;
	/**
	 * The frame duration in milliseconds, how long any given frame of animation lasts
	 */
	protected long				animationFrameDuration;
	/**
	 * Position this entity has to reach in the map (tile unit)
	 */
	protected double			finalX;
	/**
	 * Position this entity has to reach in the map (tile unit)
	 */
	protected double			finalY;
	// ============================================ //
	//                    TIMING                    //
	// ============================================ //
	/**
	 * The time since the last frame change took place
	 */
	protected long				lastFrameChange;
	/**
	 * The time since the last movement took place
	 * 
	 * @deprecated Player does not move, others movement should be handled by the server and spells timing is checked by
	 *             the main class.
	 */
	@Deprecated
	protected long				lastMove;

	/**
	 * The time since the last step of the movement change took place
	 */
	protected long				lastStepChange;

	// ============================================ //
	//                     GAME                     //
	// ============================================ //
	/**
	 * The rectangle used for this entity during collisions resolution
	 */
	protected final Rectangle	me		= new Rectangle();
	/**
	 * The frame duration in milliseconds.<br>
	 * Note: used only to calculate the "half-step" move.
	 */
	protected long				movementDelayDuration;
	// ============================================ //
	//                  ANIMATION                   //
	// ============================================ //
	/**
	 * If true the sprite will animate the walk in the desired direction
	 */
	protected boolean			moving	= false;
	/**
	 * The rectangle used for other entities during collision resolution
	 */
	protected final Rectangle	other	= new Rectangle();
	/**
	 * Position of the player in the map (tile unit)
	 */
	protected double			playerX;

	/**
	 * Position of the player in the map (tile unit)
	 */
	protected double			playerY;
	/**
	 * The sprite of the entity, the image that is drawed on the screen
	 */
	protected IImage			sprite;

	// ============================================= //
	//                   MAIN BODY                   //
	// ============================================= //
	/**
	 * Standar constructor that initialize the basic fields
	 * 
	 * @param sprite
	 *            The path and name of the sprite set
	 * @param actx
	 *            Actual position in the map (x)
	 * @param acty
	 *            Actual position in the map (y)
	 * @param plx
	 *            Position of the player in the map (x)
	 * @param ply
	 *            Position of the player in the map (y)
	 */
	public Entity(String sprite, double actx, double acty, double plx, double ply) {
		this.sprite = ResourceFactory.get().getSprite(sprite);
		this.actualX = actx;
		this.actualY = acty;
		this.finalX = actx;
		this.finalY = acty;
		this.playerX = plx;
		this.playerY = ply;
	}

	/**
	 * Draws the entity in the correct position in the map.
	 * 
	 * @param delta
	 *            Time passed since the last cycle of the game.
	 */
	public abstract void draw(long delta);

	/**
	 * Returns the acutal position (x) of this entity in the map (tile units).
	 * 
	 * @return The X position in tile unit.
	 */
	public double getX() {
		return this.actualX;
	}

	/**
	 * Return the actual position (y) of this entity in the map (tile units).
	 * 
	 * @return The Y position in tile unit.
	 */
	public double getY() {
		return this.actualY;
	}

	/**
	 * Starts the movement's animation of the entity in the desired direction.
	 * 
	 * @param delta
	 *            Time passed since the last cycle of the game
	 * @param direction
	 *            The direction of the move:<br>
	 *            - 0 : down<br>
	 *            - 1 : left<br>
	 *            - 2 : right<br>
	 *            - 3 : up<br>
	 */
	public abstract void move(long delta, int direction);

	/**
	 * Update the actual coord position of the player.<br>
	 * Doesn't affect the player itself.
	 * 
	 * @param x
	 *            The X position in tile units.
	 * @param y
	 *            The Y position in tile units.
	 */
	public void setPlayerCoord(double x, double y) {
		this.playerX = x;
		this.playerY = y;
	}

	/**
	 * Stops the animation, called when the entity is not moving anymore.
	 */
	public void stop() {
		this.moving = false;
	}

}
